﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
using BTM_Client_Application.RealTimeFilter;
using BTM_Client_Application.SupportClasses;
//using Sparrow.Chart;
using Client_Server_Interface;
using OxyPlot;
using OxyPlot.Axes;
using Series = OxyPlot.Wpf.Series;

namespace BTM_Client_Application
{
    /// <summary>
    /// Логика взаимодействия для GraphControl.xaml
    /// </summary>
    public partial class GraphControl : UserControl
    {
        //public SeriesCollection MySeriesCollection { get; set; }

        private readonly DataGridAutoInitFilter<LogRecord>   _filter;
        private ObservableCollection<LogRecord>     _records;
        private readonly PlotModel _plotModel;
        private PlotHelper _helper;

        //private ObservableCollection<Series> _plotSeries;

        //private readonly GraphHelper _helper;
        //private Legend GraphLegend;

        public GraphControl()
        {
            InitializeComponent();

            PlotBox.IsLegendVisible = true;
            PlotBox.DataContext = this;
            _records = new ObservableCollection<LogRecord>();
            List<DataGridColumn> c;
            _filter = new DataGridAutoInitFilter<LogRecord>(new LogRecord(), ref _records, out c);
            FilterContainer.Children.Add(_filter.FilterControl);
            
            _plotModel = new PlotModel();
            _plotModel.Axes.Add(new DateTimeAxis(AxisPosition.Bottom, "Date", "dd/MM"));
            _plotModel.Axes.Add(new LinearAxis(AxisPosition.Left, 0) { Title = "Count", Key = "EventCount", MajorGridlineStyle = LineStyle.Solid });
            PlotBox.Model = _plotModel;
            _helper = new PlotHelper();
            UiLanguageChanged();

        }

        private void PlotFromValues()
        {
            var filterParams = _filter.GetRequestValues();
            _helper.SetCollection(null, filterParams);
            UpdateGraph();
        }

        public void PlotFromValues(List<object> values, Dictionary<string, List<object>> filterParams)
        {
            IEnumerable<object> dist = null;
            if(values != null)
                try
                {
                    dist = values.Distinct();
                    if (dist.Count() > 8)
                    {
                        //ToImplement
                        //Оставить не больше 8 событий
                    }
                }
                catch (Exception)
                {

                }

            _helper.SetCollection(dist, filterParams);
            UpdateGraph();
        }


        class PlotHelper
        {

            public ObservableCollection<OxyPlot.Series.Series> PlotDatas { get; private set; }

            public Dictionary<string, List<object>> FilterValues { get; set; }

            //public ObservableCollection<PlotData> PlotDatas { get; set; }

            public Dictionary<string, EventInfo> EventInfos { get; set; }

            public PlotHelper()
            {
                PlotDatas = new ObservableCollection<OxyPlot.Series.Series>();
            }

            public void SetCollection(IEnumerable<object> values, Dictionary<string, List<object>> filterParams)
            {
                //filterParams[LogRecord.EventTitle] = values.Distinct().ToList();
                if (values != null)
                    filterParams[LogRecord.EventTitle].AddRange(values);
                FilterValues = filterParams;
                List<LogRecord> logList;
                try
                {
                    logList = LogRecord.WorkLogData(filterParams);
                }
                catch (ClientException ex)
                {
                    if (ex.AdditionalInfo == ClientExceptionMessage.EMPTY)
                        MessageBox.Show(Res.Rm.GetString("NothingFound", AliveInfo.CurrentCulture));
                    return;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, Res.Rm.GetString("Warning", AliveInfo.CurrentCulture));
                    return;
                }
                

                //_seriesCollection.Clear();

                PlotDatas.Clear();

                var events = new Dictionary<string, EventInfo>();
                foreach (var record in logList)
                {
                    if (!events.ContainsKey(record.Event))
                    {
                        events.Add(record.Event, new EventInfo { Name = record.Event });
                    }
                    events[record.Event].Add(record);
                }

                foreach (var info in events)
                {
                    var s = new OxyPlot.Series.ScatterSeries
                    {
                        XAxisKey = "Date",
                        YAxisKey = "EventCount",
                        Title = info.Key + ": " + info.Value.Count,
                    };
                    foreach (var plotValue in info.Value.PlotValues)
                    {
                        s.Points.Add(new DataPoint(DateTimeAxis.ToDouble(plotValue.Date), plotValue.EventCount));
                    }
                    PlotDatas.Add(s);
                }

                EventInfos = events;

                //Use events

            }

            public void ClearSeries()
            {
                PlotDatas.Clear();
            }
        }

        class EventInfo
        {
            public string Name { get; set; }

            public int Count
            {
                get { return Dates.Count; }
            }

            private readonly Dictionary<DateTime, int> _dateCounts;
            private List<DateTime> Dates { get; set; }

            public List<PlotData> PlotValues
            {
                get { return _dateCounts.Select(dateCount => new PlotData(dateCount.Key, dateCount.Value)).ToList(); }
            }

            public EventInfo()
            {
                Dates = new List<DateTime>();
                _dateCounts = new Dictionary<DateTime, int>();
            }

            public void Add(LogRecord record)
            {
                Dates.Add(record.StartTime);
                var day = record.StartTime.Subtract(record.StartTime.TimeOfDay);
                if (!_dateCounts.ContainsKey(day))
                {
                    _dateCounts.Add(day, 0);
                }
                _dateCounts[day]++;
            }
        }

        public class PlotData
        {
            public DateTime Date { get; set; }
            public int EventCount { get; set; }

            public PlotData(DateTime date, int count)
            {
                Date = date;
                EventCount = count;
            }
        }

        private void LogRefreshButton_OnClick(object sender, RoutedEventArgs e)
        {
            var vals = _filter.GetRequestValues();
            try
            {
                _helper.SetCollection(null, vals);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Some error.\r\nTry again.");
                return;
            }
            UpdateGraph();
        }

        private void UpdateGraph()
        {
            var filterParams = _helper.FilterValues;
            var title = ((DateTime)filterParams[LogRecord.StartTimeTitle][0]).ToShortDateString() + " - " +
                        ((DateTime)filterParams[LogRecord.EndTimeTitle][0]).ToShortDateString();
            _plotModel.Title = title;
            _plotModel.Series = _helper.PlotDatas;
            PlotBox.InvalidatePlot();
            _filter.SetFilterActiveValues(LogRecord.StartTimeTitle, FilterElementType.StartTime,
                                          filterParams[LogRecord.StartTimeTitle]);
            _filter.SetFilterActiveValues(LogRecord.EndTimeTitle, FilterElementType.EndTime,
                                          filterParams[LogRecord.EndTimeTitle]);
            _filter.SetFilterActiveValues(LogRecord.EventTitle, FilterElementType.StringList,
                                          filterParams[LogRecord.EventTitle]);
        }

        private void FilterClearButton_OnClick(object sender, RoutedEventArgs e)
        {
            _filter.ClearFilter();
            _helper.SetCollection(null, _filter.GetRequestValues());
            UpdateGraph();
        }

        private void SelectionButton_OnClick(object sender, RoutedEventArgs e)
        {
            var lc = new LogControl();
            try
            {
                lc.UpdateLog(_filter.GetRequestValues());

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, Res.Rm.GetString("Warning", AliveInfo.CurrentCulture));
                return;
            }
            AliveInfo.MainWindow.AppendTab(MainWindow.TabType.Log, lc);
        }

        public void UiLanguageChanged()
        {
            LogRefreshButtonContainer.Children.Clear();
            LogRefreshButtonContainer.Children.Add(new ButtonWithImage((BitmapImage)FindResource("RefreshDark"),
                                                                       Res.Rm.GetString("Refresh", AliveInfo.CurrentCulture),
                                                                       LogRefreshButton_OnClick));

            FilterClearButtonContainer.Children.Clear();
            FilterClearButtonContainer.Children.Add(new ButtonWithImage((BitmapImage)FindResource("ResetDark"),
                                                                       Res.Rm.GetString("Reset", AliveInfo.CurrentCulture),
                                                                       FilterClearButton_OnClick));

            SelectionButtonContainer.Children.Clear();
            SelectionButtonContainer.Children.Add(new ButtonWithImage((BitmapImage)FindResource("ListCreateDark"),
                                                                       Res.Rm.GetString("Selection", AliveInfo.CurrentCulture),
                                                                       SelectionButton_OnClick));
        }
    }
}
